﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GomLib;

namespace GomTest.GenTalents
{
    class GenTalentsCommand /*: ICommandRunner*/
    {
        const ulong NameLookupKey = 15685385242400905286;
        const ulong DescLookupKey = 2806211896052149513;
        const long StringIdOffset = 0x7377E00000000;

        public string[] Commands
        {
            get { return new string[] { "gentalents", "gt" }; }
        }

        public string Help
        {
            get { return "Generate CoffeeScript for Talent Calculator\nUsage: gentalents"; }
        }

        public bool ParametersValid(List<string> parameters)
        {
            return true;
        }

        /// <summary>
        /// 1) Open sklSkillTreePrototype
        /// 2) Load sklSkillTreePackageList
        ///  Foreach AdvancedClass,List<sklPackageInfo>
        ///    Foreach sklPackageInfo
        ///      Create new TalentTree
        ///      TalentTree.AdvancedClass = AdvancedClass
        ///      TalentTree.Color = sklPackageInfo.sklSkillTreeColor
        ///      abilityPackage = Load sklPackageInfo.sklAbilityPackageId
        ///      talentLayoutName = abilityPackage.Name + "_layoutprototype"
        ///      talentLayout = Load talentLayoutName
        ///      Read talents, prereqs, and positions from talentLayout
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public bool RunCommand(List<string> parameters)
        {
            
            List<AdvancedClass> advancedClassList = new List<AdvancedClass>(); // list of all advanced classes
            Dictionary<string, TalentTree> talentTrees = new Dictionary<string,TalentTree>(); // map tree layout file to TalentTree struct
            Dictionary<string, Dictionary<string, TalentInfo>> talentLookup = new Dictionary<string,Dictionary<string,TalentInfo>>();

            GomLib.DataObjectModel.Load();
            GomLib.ModelLoader.AbilityLoader ablLoader = new GomLib.ModelLoader.AbilityLoader();

            var stringTable = GomLib.StringTable.Find("str.abl.player.skill_trees");

            var skillTreeProto = DataObjectModel.GetObject("sklSkillTreePrototype");
            var packageList = skillTreeProto.Data.Get<Dictionary<object,object>>("sklSkillTreePackageList");
            int acIdx = 0;
            foreach (var kvp in packageList)
            {
                GomObject advClass = DataObjectModel.GetObject((ulong)kvp.Key);
                int advClassNameId = (int)advClass.Data.Get<long>("chrAdvancedClassDataNameId");
                string advClassId = advClass.Name.Substring(18); // Remove 'class.pc.advanced.'
                // TODO: Need to read Advanced Class name from string table
                AdvancedClass ac = new AdvancedClass()
                {
                    Id = advClassId,
                    Index = acIdx,
                    Version = 2,
                    Trees = new List<string>(3)
                };
                ac.Trees.Add(null);
                ac.Trees.Add(null);
                ac.Trees.Add(null);
                advancedClassList.Add(ac);

                acIdx++; // Increment AdvancedClass index

                var packageInfoList = (List<object>)kvp.Value;
                foreach (GomObjectData pkgInfo in packageInfoList)
                {
                    GomObject abilityPackage = DataObjectModel.GetObject(pkgInfo.Get<ulong>("sklAbilityPackageId"));

                    // Create TalentTree

                    TalentTree tree = new TalentTree();
                    tree.Position = (int)pkgInfo.Get<long>("sklSkillTreePosition");
                    tree.Color = pkgInfo.Get<string>("sklSkillTreeColor");
                    tree.Prefix = pkgInfo.Get<string>("sklSkillTreePrefix");
                    int treeNameId = (int)pkgInfo.Get<ulong>("sklAbilityPackageName");
                    tree.Talents = new List<TalentInfo>();
                    tree.Id = abilityPackage.Name.Substring(14).Replace('.', '_'); //Remove pkg.abilities. and replace dots with underscores
                    //tree.Name = tree.Id; // TODO: Lookup Talent Tree name in some string table somewhere
                    tree.Name = stringTable.GetText(StringIdOffset + (long)pkgInfo.Get<ulong>("sklAbilityPackageName"), "");
                    ac.Name = stringTable.GetText(StringIdOffset + (long)pkgInfo.Get<ulong>("sklAbiltyTabName"), "");
                    tree.Package = abilityPackage.Name;
                    tree.LayoutFile = abilityPackage.Name + "_layoutprototype";
                    talentTrees.Add(tree.Package, tree);
                    ac.Trees[tree.Position - 1] = tree.Id;
                    // ac.Trees.Add(tree.Id);
                    TorLib.Icons.Add(tree.Color);
                    TorLib.Icons.AddCodex(tree.Color);
                    //TorLib.Icons.AddMap(tree.Color);
                    TorLib.Icons.AddPortrait(tree.Color);

                    var talentLayout = DataObjectModel.Get<GomObject>(tree.LayoutFile);
                    var treeLayout = talentLayout.Data.Get<Dictionary<object,object>>("sklSkillTreeLayoutList");
                    Dictionary<string, TalentInfo> treeTalentMap = new Dictionary<string, TalentInfo>();
                    talentLookup[tree.Id] = treeTalentMap;

                    foreach (var treeRow in treeLayout)
                    {
                        int rowNum = 7 - (int)(long)treeRow.Key;
                        foreach (var treeCol in (Dictionary<object,object>)treeRow.Value)
                        {
                            int colNum = (int)(long)treeCol.Key - 1;
                            var treeEntry = (GomObjectData)treeCol.Value;
                            if (!treeEntry.ContainsKey("sklSkillTreeEntryId"))
                            {
                                // This entry has no ability reference
                                continue;
                            }

                            GomLib.Models.Ability abl = new GomLib.Models.Ability();
                            GomObject ablObj = DataObjectModel.GetObject(treeEntry.Get<ulong>("sklSkillTreeEntryId"));
                            ablLoader.LoadObject(abl, ablObj);

                            TalentInfo talentInfo = new TalentInfo()
                            {
                                Row = rowNum,
                                Col = colNum,
                                Fqn = ablObj.Name,
                                Id = ablObj.Name.Substring(tree.Prefix.Length + 1)
                            };
                            tree.Talents.Add(talentInfo);
                            treeTalentMap[talentInfo.Id] = talentInfo;

                            GomObject prereq = null;
                            if (treeEntry.ContainsKey("sklSkillTreeEntryPrereq"))
                            {
                                prereq = DataObjectModel.GetObject(treeEntry.Get<ulong>("sklSkillTreeEntryPrereq"));
                                talentInfo.Prereq = prereq.Name;
                            }

                            talentInfo.MaxPoints = (int)treeEntry.Get<ulong>("sklSkillTreeEntryMaxPoints");

                            talentInfo.Ability = abl;
                            TorLib.Icons.Add(abl.Icon);
                        }
                    }
                }
            }

            TalentScriptWriter.BuildTalentInfoScript(advancedClassList, talentTrees, talentLookup);
            string outpath = System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"images\");
            TorLib.Icons.SaveTo(outpath);
            //TorLib.Icons.SaveTo("c:\\code\\swtorfiles\\talent_icons\\", true);

            return true;
        }
    }
}
